#ifndef ENTITYLIGHT_H
#define ENTITYLIGHT_H
#include "Vector3.h"

class EntityLight
{
public:
    // 光源类型枚举
    enum class LightType { DIRECTIONAL, POINT, SPOT };

    // 光源类型
    LightType Type;

    // 光源位置
    Vector3 Position;

    // 光源方向
    Vector3 Direction;

    // 光照范围
    float Range;

    // 聚光灯角度
    float Angle;

    // 光源颜色
    Vector3 Color;

    // 光源绑定至相机
    bool BindCamera;

    /**
     * @brief 构造函数
     */
    EntityLight()
    {
        Type = LightType::DIRECTIONAL;
        Position = Vector3(0.0f, 0.0f, 0.0f);
        Direction = Vector3(0.0f, 1.0f, -1.0f);
        Range = 100.0f;
        Angle = 1.57f;
        Color = Vector3(1.0f, 1.0f, 1.0f);
        BindCamera = false;
    }

    /**
     * @brief 获取脚本代码
     * @param prefix 空格对齐
     * @return
     */
    QString Script(const QString& prefix = "")
    {
        const QString format1 = "graphics.directionalLight(%1,%2)";
        const QString format2 = "graphics.pointLight(%1,%2,%3)";
        const QString format3 = "graphics.spotLight(%1,%2,%3,%4,%5)";
        QStringList command;
        if (BindCamera)
        {
            const QString sPosition = "lightx,lighty,lightz";
            const QString sDirection = "lightdirx,lightdiry,lightdirz";
            command.append(prefix + "updateLight = function()");
            if (Type != LightType::DIRECTIONAL) command.append(prefix + "local " + sPosition + " = camera.position()");
            if (Type != LightType::POINT) command.append(prefix + "local " + sDirection + " = camera.direction()");
            if (Type == LightType::DIRECTIONAL) command.append(prefix + QString(format1).arg(sDirection, Color.ToString()));
            if (Type == LightType::POINT) command.append(prefix + QString(format2).arg(sPosition).arg(Range).arg(Color.ToString()));
            if (Type == LightType::SPOT) command.append(prefix + QString(format3).arg(sPosition, sDirection).arg(Angle).arg(Range).arg(Color.ToString()));
            command.append(prefix + "end");
            return command.join('\n');
        }
        else
        {
            command.append(prefix + "updateLight = nil");
            if (Type == LightType::DIRECTIONAL) command.append(prefix + QString(format1).arg(Direction.ToString(), Color.ToString()));
            if (Type == LightType::POINT) command.append(prefix + QString(format2).arg(Position.ToString()).arg(Range).arg(Color.ToString()));
            if (Type == LightType::SPOT) command.append(prefix + QString(format3).arg(Position.ToString(), Direction.ToString()).arg(Angle).arg(Range).arg(Color.ToString()));
            return command.join('\n');
        }
    }

    /**
     * @brief 解析字符串
     * @param type
     */
    void Parse(const QString& type)
    {
        if (type == "directional") Type = LightType::DIRECTIONAL;
        else if (type == "point") Type = LightType::POINT;
        else if (type == "spot") Type = LightType::SPOT;
    }

    /**
     * @brief 重载 ToString
     * @return
     */
    QString ToString() const
    {
        if (Type == LightType::DIRECTIONAL) return "directional";
        if (Type == LightType::POINT) return "point";
        if (Type == LightType::SPOT) return "spot";
        return "";
    }
};

#endif // ENTITYLIGHT_H
